/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2025-06-28     17247       the first version
 */
/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2025-05-05     17247       the first version
 * 2025-06-30     Optimized   Fixed deadlock issues
 */
#include <rtthread.h>
#include "ssd1306.h"
#include "sht3x.h"
#include <math.h>
#include "sht31_thread.h"
#include <stdlib.h>

volatile uint8_t sht31_init_complete = 0;
float global_temperature = 0.0f;
float global_humidity = 0.0f;
rt_mutex_t i2c_mutex = RT_NULL;

static volatile uint8_t sensor_ready = 0;
static sht3x_device_t sht_dev = RT_NULL;

int sht31_display_init(void);

static void sht31_display_thread(void *parameter)
{
    char temp_label[8] = "T:";
    char humi_label[8] = "H:";
    char temp_value[10];
    char humi_value[10];
    char temp_unit[3] = "C";
    char humi_unit[3] = "%";
    rt_kprintf("[SENSOR] Starting initialization...\n");

    // 加锁访问I2C总线
    if (rt_mutex_take(i2c_mutex, RT_WAITING_FOREVER) != RT_EOK)
    {
        rt_kprintf("[SENSOR] Failed to take i2c mutex\n");
        goto display_error;
    }

    sht_dev = sht3x_init("i2c1", SHT3X_ADDR_PD);

    if (sht_dev == RT_NULL)
    {
        rt_kprintf("[SHT31] Init failed\n");
        rt_mutex_release(i2c_mutex);
        goto display_error;
    }

    rt_mutex_release(i2c_mutex);

    sensor_ready = 1;
    rt_kprintf("[SENSOR] Hardware initialized, waiting stabilization\n");
    rt_thread_mdelay(200); // 必要的短延迟

    // 初始化OLED - 确保I2C总线空闲
    ssd1306_Init();
    ssd1306_Fill(Black);
    ssd1306_UpdateScreen();

    sht31_init_complete = 1;
    rt_kprintf("[SENSOR] Initialization complete\n");

    while (1)
    {
        // 加锁访问I2C总线
        if (rt_mutex_take(i2c_mutex, 1000) != RT_EOK)
        {
            rt_kprintf("[SENSOR] I2C mutex timeout\n");
            continue;
        }

        rt_err_t result = sht3x_read_singleshot(sht_dev);
        rt_mutex_release(i2c_mutex);

        if (result != RT_EOK)
        {
            rt_kprintf("[SHT31] Read failed (0x%08X)\n", result);
            ssd1306_Fill(Black);
            ssd1306_SetCursor(5, 10);
            ssd1306_WriteString("READ ERROR", Font_7x10, White);
            ssd1306_UpdateScreen();
            rt_thread_mdelay(500);
            continue;
        }

        global_temperature = sht_dev->temperature;
        global_humidity = sht_dev->humidity;

        // 安全处理浮点数
        if (isnan(global_temperature) || isnan(global_humidity))
        {
            rt_kprintf("[SENSOR] Invalid sensor data\n");
            continue;
        }

        // 温度值处理
        int temp_int = (int) round(global_temperature * 10);  // 乘以10后四舍五入
        int temp_whole = temp_int / 10;                     // 整数部分
        int temp_frac = abs(temp_int % 10);                 // 小数部分（取绝对值）

        // 湿度值处理
        int humi_int = (int) round(global_humidity * 10);     // 乘以10后四舍五入
        int humi_whole = humi_int / 10;                      // 整数部分
        int humi_frac = abs(humi_int % 10);                 // 小数部分（取绝对值）

        // 格式化字符串
        rt_snprintf(temp_value, sizeof(temp_value), "%d.%d", temp_whole, temp_frac);
        rt_snprintf(humi_value, sizeof(humi_value), "%d.%d", humi_whole, humi_frac);

        // OLED显示更新
        ssd1306_Fill(Black);

        // 温度显示
        ssd1306_SetCursor(5, 5);
        ssd1306_WriteString(temp_label, Font_7x10, White);
        ssd1306_SetCursor(25, 5);
        ssd1306_WriteString(temp_value, Font_7x10, White);
        ssd1306_SetCursor(70, 5);
        ssd1306_WriteString(temp_unit, Font_7x10, White);

        // 湿度显示
        ssd1306_SetCursor(5, 25);
        ssd1306_WriteString(humi_label, Font_7x10, White);
        ssd1306_SetCursor(25, 25);
        ssd1306_WriteString(humi_value, Font_7x10, White);
        ssd1306_SetCursor(70, 25);
        ssd1306_WriteString(humi_unit, Font_7x10, White);

        ssd1306_UpdateScreen();

        rt_thread_mdelay(2000);
    }

    display_error:
    // 确保释放互斥锁
    if (i2c_mutex)
    {
        rt_mutex_release(i2c_mutex);
    }

    ssd1306_Fill(Black);
    ssd1306_SetCursor(5, 10);
    ssd1306_WriteString("SENSOR ERROR", Font_7x10, White);
    ssd1306_UpdateScreen();

    // 永久显示错误状态
    while (1)
    {
        rt_thread_mdelay(2000);
    }
}

float get_global_temperature(void)
{
    return sensor_ready ? global_temperature : NAN;
}
float get_global_humidity(void)
{
    return sensor_ready ? global_humidity : NAN;
}

uint8_t sht31_is_initialized(void)
{
    return sht31_init_complete;
}

int sht31_display_init(void)
{
    // 创建I2C互斥锁
    i2c_mutex = rt_mutex_create("i2c_mutex", RT_IPC_FLAG_FIFO);
    if (!i2c_mutex)
    {
        rt_kprintf("[I2C] Mutex create failed!\n");
        return -RT_ERROR;
    }

    // 创建传感器线程 - 降低优先级
    rt_thread_t thread;
    thread = rt_thread_create("sht_disp", sht31_display_thread,
    RT_NULL, 2048, 20, 10); // 优先级20

    if (thread != RT_NULL)
    {
        rt_thread_startup(thread);
        rt_kprintf("SHT31 display thread created\n");
        return RT_EOK;
    }

    rt_kprintf("Failed to create display thread\n");
    return -RT_ERROR;
}

INIT_APP_EXPORT(sht31_display_init);
